﻿using Com.Lancetinc.Evs.Controls;
using Com.Lancetinc.Evs.Events;
using Com.Lancetinc.Evs.Helpers;
using Com.Lancetinc.Evs.Services;
using MahApps.Metro.IconPacks;
using Prism.Events;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Com.Lancetinc.Evs
{
    public partial class MainWindow
    {
        public static MainWindow Instance { get; private set; }

        public MainWindowViewModel ViewModel { get; }

        public MainWindow()
        {
            if (!LoginHelper.Login(out var subWindowShown))
            {
                this.Close();
                return;
            }

            Instance = this;
            ViewModel = new MainWindowViewModel();
            ActiveApp.Instance.MainWindowVm = ViewModel;

            InitializeComponent();

            this.DataContext = ViewModel;

            RegisterEvents();
#if DEBUG
            // 调试的时候显示最大最小化按钮
            if (Debugger.IsAttached)
            {
                this.WindowState = WindowState.Normal;
                //this.UseNoneWindowStyle = false;
                this.ShowTitleBar = true;
            }
#endif
        }

        private void ThisWindow_Loaded(object sender, RoutedEventArgs e)
        {
            ActiveApp.Instance.InstManager.Start(this.Dispatcher);
            TempDirHelper.DeleteTempImageFiles();

            ExperRunController.RepairExperEndTimeWhenAppStarted();
            ResetWinStateButtonIcon();
        }

        private void MainWindow_ContentRendered(object sender, EventArgs e)
        {
            SplashScreenWin.CloseWin();
        }

        private UserMouseMoveDetector _mouseMoveDetector;
        private void RegisterEvents()
        {
            KnownAppEvents.RecordStateChangedEvent.Subscribe(InstrumentRecordStateChanged, ThreadOption.UIThread);
            KnownAppEvents.RequireShowCapturedImageEvent.Subscribe(OnRequireShowCapturedImageEvent,
                ThreadOption.UIThread);
            KnownAppEvents.RequireChangeFullScreenStateEvent.Subscribe(OnRequireChangeFullScreenStateEvent,
                ThreadOption.UIThread);

            KnownAppEvents.VideoRecordStartedEvent.Subscribe(OnVideoRecordStarted, ThreadOption.UIThread);
            KnownAppEvents.VideoRecordStoppedEvent.Subscribe(OnVideoRecordStopped, ThreadOption.UIThread);

            KnownAppEvents.ReportTemplatePreviewChanged.Subscribe(OnReportTemplatePreviewChanged, ThreadOption.UIThread);

            RegisterMouseMoveEvents();
            this.ContentRendered += MainWindow_ContentRendered;
            this.StateChanged += MainWindow_StateChanged;
        }

        private void MainWindow_StateChanged(object sender, EventArgs e)
        {
            ResetWinStateButtonIcon();
        }

        #region 鼠标移动
        private void RegisterMouseMoveEvents()
        {
            _mouseMoveDetector = new UserMouseMoveDetector(this);
            _mouseMoveDetector.MouseMoved += _mouseMoveDetector_MouseMoved;
            _mouseMoveDetector.MouseStopped += _mouseMoveDetector_MouseStopped;
            this.MouseDown += MainWindow_MouseDown;
        }

        private void MainWindow_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            if (!_mouseMoveDetector.DetectStarted)
                return;

            KnownAppEvents.PublishRequireChangeFullScreenState(false);
        }

        private void _mouseMoveDetector_MouseMoved(object sender, EventArgs e)
        {
            KnownAppEvents.PublishRequireChangeFullScreenState(false);
        }

        private void _mouseMoveDetector_MouseStopped(object sender, EventArgs e)
        {
            KnownAppEvents.PublishRequireChangeFullScreenState(true);
        }
        #endregion

        /// <summary>
        /// 请求显示截图列表
        /// </summary>
        /// <param name="args"></param>
        private void OnRequireShowCapturedImageEvent(RequireShowCapturedImageEventArgs args)
        {
            // 显示已截屏的图片
            CtrlCapturedImage.SetExper(args.ExperInfo);
            CtrlCapturedImage.ShowImage(args.ImageName);

            ActiveApp.Instance.MainWindowVm.ControlButtonVm.IsShowCapturedImage = true;
            if (args.ShowDuration.HasValue)
            {
                TryDismissCapturedImageCtrl((int)args.ShowDuration.Value.TotalMilliseconds);
            }
        }

        private void TryDismissCapturedImageCtrl(int delay)
        {
            var btnVm = ActiveApp.Instance.MainWindowVm.ControlButtonVm;
            WpfHelper.ExecLaterEx("DismissCapturedImage", () =>
             {
                 if (!btnVm.IsShowCapturedImage)
                     return; // 已经隐藏

                 if (CtrlCapturedImage.IsHover)
                 {
                     TryDismissCapturedImageCtrl(delay);
                     return; // 鼠标放在上面，则延迟隐藏
                 }
                 btnVm.IsShowCapturedImage = false;
             }, delay);
        }

        private void InstrumentRecordStateChanged(RecordStateChangedEventArgs e)
        {
            var recording = e.Recording;
            if (recording)
            {
                // 不知道为什么，如果CtrlMedia一开始就设置为Collapsed,那么有登录页面的情况下，第一次播放会显示黑屏
                // 错误消息：[InvalidComObjectException:COM对象与其基础RCW分开后不能再使用该对象]
                // 因此只能把初始Opacity设置为0
                // 2022/09/26: RadWebCam初始化的时候会去查找父窗口及其Handle,因此要在使用RadWebCam前确保其在窗口中
                if (CtrlMedia.Opacity < 1)
                    CtrlMedia.Opacity = 1;
                CtrlMedia.Visibility = Visibility.Visible;
                _mouseMoveDetector.Start();
            }
            else
            {
                CtrlMedia.Visibility = Visibility.Collapsed;
                _mouseMoveDetector.Stop();
                KnownAppEvents.PublishRequireChangeFullScreenState(false);
            }
        }

        private void OnRequireChangeFullScreenStateEvent(RequireChangeFullScreenStateEventArgs args)
        {
            if (this.ViewModel.IsFullScreen == args.IsFullScreen)
                return;

            this.ViewModel.IsFullScreen = args.IsFullScreen;
            OnIsFullScreenChanged(args.IsFullScreen);
        }

        private void ThisWindow_Unloaded(object sender, RoutedEventArgs e)
        {
            ActiveApp.Instance.InstManager.Stop();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            if (ActiveApp.Instance.Instrument.VideoRecording)
            {
                ViewModel.ShowPinnedError(Msgs.CannotExitWhenRecording, dismissDelay: TimeSpan.FromSeconds(3));
                e.Cancel = true;
                return;
            }

            base.OnClosing(e);
        }

        private void CtrlCapturedImage_OnImageCountChanged(object sender, CaptureImageChangedEventArgs e)
        {
            KnownAppEvents.PublishCaptureImageChanged(e.ExperInfo, e.Reason);
        }

        private void LevsFlyoutsControl_OnIsOpenChanged(object sender, EventArgs e)
        {
            var flyouts = FlyoutsControl.GetFlyouts().ToList();
            // 已截图片页面不显示遮罩(正在录像)
            var showMask = flyouts.Any(x => x.IsOpen && !LevsFlyoutsControl.GetDisableMask(x));
            CtrlFlyoutMask.Visibility = showMask ? Visibility.Visible : Visibility.Collapsed;
        }

        private void OnVideoRecordStarted(VideoRecordStartedEventArgs args)
        {
            ChangeTheme(LevsTheme.Dark);
        }

        private void OnVideoRecordStopped(VideoRecordStoppedEventArgs args)
        {
            ChangeTheme(LevsTheme.Light);
        }

        private void OnReportTemplatePreviewChanged(ReportTemplatePreviewChangedEventArgs args)
        {
            ShowHideReportTemplateSettingPreview(args.IsShow);
        }

        private void ShowHideReportTemplateSettingPreview(bool show)
        {
            if (!show)
            {
                GridReportTemplateSettingPreview.Child = null;
                GridReportTemplateSettingPreview.Visibility = Visibility.Collapsed;
                return;
            }

            ReportTemplateSettingPreviewUserControl ctrl = null;
            if (GridReportTemplateSettingPreview.Child != null)
            {
                ctrl = GridReportTemplateSettingPreview.Child as ReportTemplateSettingPreviewUserControl;
            }
            else
            {
                var left = CtrlSettingFlyout.ActualWidth;
                ctrl = new ReportTemplateSettingPreviewUserControl
                {
                    VerticalAlignment = VerticalAlignment.Center
                };
                GridReportTemplateSettingPreview.Child = ctrl;
                GridReportTemplateSettingPreview.Margin = new Thickness(left, 0, 0, 0);
                var a4Size = PaperSizeHelper.GetA4PaperSize();

            }
            ctrl?.Preview();
            GridReportTemplateSettingPreview.Visibility = Visibility.Visible;

            CtrlSettingFlyout.IsOpenChanged -= CtrlSettingFlyout_IsOpenChanged;
            CtrlSettingFlyout.IsOpenChanged += CtrlSettingFlyout_IsOpenChanged;
        }

        private void CtrlSettingFlyout_IsOpenChanged(object sender, RoutedEventArgs e)
        {
            CtrlSettingFlyout.IsOpenChanged -= CtrlSettingFlyout_IsOpenChanged;
            ShowHideReportTemplateSettingPreview(false);
        }

        #region Theme

        private void ChangeTheme(LevsTheme theme)
        {
            ThemeHelper.ChangeTheme(MainGrid, theme);
            // 背景色
            if (theme == LevsTheme.Light)
            {
                var bg = (Brush)MainGrid.FindResource("MahApps.Brushes.ThemeBackground");
                this.Background = bg;
            }
            else
            {
                this.Background = ThemeHelper.Brushes.MainWinBgDark.Value;
            }
        }
        #endregion

        private Lazy<Storyboard> SbHide => new(() => (Storyboard)FindResource("HideStoryboard"));
        private Lazy<Storyboard> SbShow => new(() => (Storyboard)FindResource("ShowStoryboard"));

        private void OnIsFullScreenChanged(bool isFullScreen)
        {
            if (isFullScreen)
            {
                var hideSb = SbHide.Value;
                hideSb.Begin(PanelTopButtons);
                hideSb.Begin(PanelBottomButtons);
            }
            else
            {
                var showSb = SbShow.Value;
                showSb.Begin(PanelTopButtons);
                showSb.Begin(PanelBottomButtons);
            }
        }

        private void ResetWinStateButtonIcon()
        {
            var sts = this.WindowState;
            if (sts == WindowState.Maximized)
            {
                BtnSwitchWinState.Icon = PackIconLevsKind.WinSizeMax.ToString();
            }
            else if (sts == WindowState.Normal)
            {
                BtnSwitchWinState.Icon = PackIconLevsKind.WinSizeNormal.ToString();
            }
        }

        private void BtnSwitchWinState_Click(object sender, RoutedEventArgs e)
        {
            if (this.WindowState == WindowState.Maximized)
            {
                SystemCommands.RestoreWindow(this);
            }
            else if (this.WindowState == WindowState.Normal)
            {
                SystemCommands.MaximizeWindow(this);
            }
        }
    }
}